const marked = require("marked");
const markToc = require("markdown-toc");
const highlight = require("highlight.js");

/**
 * Markdown文档转换相关的服务
 */
export default class extends think.Service {
  /**
   * generate toc name
   * @param  {String} name []
   * @return {String}      []
   */
  generateTocName(name) {
    name = name
      .trim()
      .replace(/\s+/g, "")
      .replace(/\)/g, "")
      .replace(/[(,]/g, "-")
      .toLowerCase();
    if (/^[\w-]+$/.test(name)) {
      return name;
    }
    return `toc-${think.md5(name).slice(0, 3)}`;
  }

  generateToc(content) {
    const tocContent = marked(markToc(content).content).replace(
      /<a\s+href="#([^"]+)">([^<>]+)<\/a>/g,
      (a, b, c) => {
        return `<a href="#${this.generateTocName(c)}">${c}</a>`;
      }
    );
    return tocContent;
  }

  /**
   * markdown to html
   * @return {} []
   */

  markdownToHtml(content, hasToc = false, tocClass = "toc") {
    const renderer = new marked.Renderer();
    let markedContent = marked(content, {
      // breaks: true,
      // headerIds: true,
      highlight(code) {
        return highlight.highlightAuto(code).value;
      },
      renderer: renderer,
    }).replace(/<h(\d)[^<>]*>(.*?)<\/h\1>/g, (a, b, c) => {
      if (b | (0 === 2)) {
        return `<h${b} id="${this.generateTocName(c)}">${c}</h${b}>`;
      }
      return `<h${b} id="${this.generateTocName(
        c
      )}"><a class="anchor" href="#${this.generateTocName(
        c
      )}"></a>${c}</h${b}>`;
    });

    if (hasToc) {
      const tocContent = this.generateToc(content);
      markedContent = markedContent.replace(
        /<h(\d)[^<>]*>([^<>]+)<\/h\1>/,
        (a, b, c) => {
          return `${a}<div class="${tocClass}">${tocContent}</div>`;
        }
      );
    }

    return markedContent; //Highlight HTML content
  }
}